package cz.data.common.security.utils;

import cz.data.common.core.DataConstant;
import cz.data.common.exception.DataException;
import cz.data.common.security.core.token.JwtTokenAuthentication;
import cz.data.common.support.security.DynamicRequestMatcherRule;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

public class SecurityUtils {

    public static Jwt requireSecurityJwt() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof JwtTokenAuthentication) {
            return ((JwtTokenAuthentication) authentication).getJwt();
        } else {
            throw new DataException("上下文不存在登录Jwt凭证");
        }
    }

    public static String bearerTokenResolver(HttpServletRequest request) {
        return removeTokenType(request.getHeader(DataConstant.Token.USER_HEADER));
    }

    public static String removeTokenType(String token) {
        if (StringUtils.startsWith(token, "Bearer ")) {
            token = token.substring(7);
        }
        return token;
    }

    public static String addBearerTokenType(String tokenValue) {
        if (tokenValue == null)
            return null;
        if (!StringUtils.startsWith(tokenValue, "Bearer ")) {
            tokenValue = "Bearer " + tokenValue;
        }
        return tokenValue;
    }

    public static void requestMatchers(HttpSecurity.RequestMatcherConfigurer request,
                                       List<DynamicRequestMatcherRule> requestMatchers) {
        for (DynamicRequestMatcherRule requestMatcher : requestMatchers) {
            request.mvcMatchers(requestMatcher.method(), requestMatcher.patterns());
        }
    }

    public static void authorizeRequests(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry request,
                                         List<DynamicRequestMatcherRule> requestMatchers) {
        for (DynamicRequestMatcherRule matcher : requestMatchers) {
            request.mvcMatchers(matcher.method(), matcher.patterns()).access(matcher.access());
        }
    }
}
